import redis
import logging
import time
import json
import threading
from setting import JUDGMENT_CYCLE, LAST_ESP_SET, NOW_ESP_SET, COMPLETE_JUDGMENT_CYCLE
from util import get_mac_address, send_mqtt_message, mqtt_status_callback, set_cabinet_current_status, set_cabinet_current_order_status

from serial_rfid_reader import RfidSerialPortMethod
from sound_playback import SoundPlayback


logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)

class Inventory:

    def __enter__(self):

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):

        self.r.close()

    def __init__(self, task_number) -> None:

        self.task_number = task_number

        # 创建一个Redis连接
        self.r = redis.Redis(host='localhost', port=6379, db=0)


    def start_inventory(self): # 开启盘点

        if self.r.exists(LAST_ESP_SET):

            # 清空上次集合
            self.r.delete(LAST_ESP_SET)

        if self.r.exists(NOW_ESP_SET):

            self.r.rename(NOW_ESP_SET, LAST_ESP_SET) # 更改集合名字为上次盘点集合

        spm = RfidSerialPortMethod()

        spm.scan_rfid()

    def end_inventory(self): # 停止盘点

        spm = RfidSerialPortMethod()

        spm.stop_scan_rfid()


    def sentry_scan_rfid_(self): # 监测扫描结果

        # 持续监测集合元素数量
        while True:
            # 获取集合的初始元素数量
            initial_count = self.r.scard(NOW_ESP_SET)

            logger.info("initial_count: {}".format(initial_count))
            # 延时判定周期
            time.sleep(JUDGMENT_CYCLE)
            # 获取当前集合的元素数量
            current_count = self.r.scard(NOW_ESP_SET)
            
            # 如果1秒内集合元素数量没有增长，则打印“打扫完成”并退出循环
            if current_count == initial_count:
            
                self.end_inventory() # 终止扫描任务

                break

        return True
    
    def sentry_scan_rfid(self): # 监测扫描结果

        time.sleep(COMPLETE_JUDGMENT_CYCLE)
            
        self.end_inventory() # 终止扫描任务

        return True
    
    def send_now_esp_set_to_mqtt(self, task_number=None):

        '''发送now_esp_set到数据中心'''

        now_esp_set = self.r.smembers(NOW_ESP_SET)

        now_esp_list = [item.decode() for item in now_esp_set]

        if task_number == None:

            msg = {
                "mac": get_mac_address(),
                "esp_list": now_esp_list
            }

        else:

            msg = {
                "mac": get_mac_address(),
                "esp_list": now_esp_list,
                "orderid": task_number
            }



        send_mqtt_message(message=json.dumps(msg), topic="rfid_cabinet/esp_list")

        return now_esp_list
    
    def flow(self): 
        '''盘点全流程'''

        mqtt_status_callback("正在盘点") # 同步状态

        set_cabinet_current_status("正在盘点")

        self.start_inventory() # 开启盘点

        if self.sentry_scan_rfid(): # 监测扫描结果

            logger.info("盘点结束")

            self.send_now_esp_set_to_mqtt(task_number=self.task_number)

            mqtt_status_callback("盘点结束") # 同步状态

            set_cabinet_current_status("盘点结束")

            set_cabinet_current_order_status("无任务")

            SoundPlayback().inventory_commpleted_sound_thread.start() 




    

if __name__ == "__main__":

    import time
    import random

    task_number = "pdd" + str(int(round(time.time() * 1000))) + str(random.randint(10000, 99999))

    while True:

        try:
    
            with Inventory(task_number=task_number) as inv:

                inv.flow()

        except Exception as e:

            logger.error(str(e))

        else:

            logger.info("开机盘点结束")

            break
